﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Office.Automatic.Library.Data.Utils.Excel
{
    public class DataConverter
    {
        public object? ConvertTo(object value, Type targetType, CellDataType dataType ,string? annotation)
        {
            if (targetType == typeof(string))
            {
                return ToText(value, dataType, annotation);
            }else if (targetType == typeof(int))
            {
                return ToInt(value, dataType, annotation);
            }else if (targetType == typeof(long))
            {
                return ToLong(value, dataType, annotation);
            }else if (targetType == typeof(float))
            {
                return ToSingle(value, dataType, annotation);
            }else if (targetType == typeof(double))
            {
                return ToDouble(value, dataType, annotation);
            }else if (targetType == typeof(decimal))
            {
                return ToDecimal(value, dataType, annotation);
            }else if (targetType == typeof(DateTime))
            {
                return ToDateTime(value, dataType, annotation);
            }

            throw new ArgumentException(null, nameof(dataType));
        }

        public TValue? ConvertTo<TValue>(object value, CellDataType dataType, string? annotation) 
        {
            var result = ConvertTo(value, typeof(TValue), dataType, annotation);

            if (result != null)
                return (TValue)result;
            else
                return default;
        }

        public virtual string? ToText(object? value, CellDataType dataType, string? annotation)
        {
            if (value == null)
                return null;

            if (dataType == CellDataType.String)
            {
                return (string)value;
            }else if (dataType == CellDataType.Numeric)
            {
                var result = value.ToString();
                return result ?? "";
            }else if (dataType == CellDataType.Boolean)
            {
                return ((bool)value) ? "true" : "false";
            }

            throw new ArgumentException(null, nameof(dataType));
        }

        public virtual int ToInt(object value, CellDataType dataType, string? annotation)
        {
            return Convert.ToInt32(value);
        }

        public virtual long ToLong(object value, CellDataType dataType, string? annotation)
        {
            return Convert.ToInt64(value);
        }
        public virtual float ToSingle(object value, CellDataType dataType, string? annotation)
        {
            return Convert.ToSingle(value);
        }
        public virtual double ToDouble(object value, CellDataType dataType, string? annotation)
        {
            return Convert.ToDouble(value);
        }

        public virtual decimal ToDecimal(object value, CellDataType dataType, string? annotation)
        {
            return Convert.ToDecimal(value);
        }

        public virtual DateTime ToDateTime(object value, CellDataType dataType, string? annotation)
        {
            var v = value.ToString();
            if (string.IsNullOrEmpty(v))
                throw new ArgumentException(null, nameof(value));
            return DateTime.Parse(v, CultureInfo.InvariantCulture);
        }
    }
}
